package com.ts.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;



public class FtpConnector {
	public static final String separator="/";//目录分隔符
	FTPClient client=null;
	/**
	 * 连接到ftp服务器
	 * @param ip
	 * @param port
	 * @param username
	 * @param password
	 * @return
	 */
	public boolean connectFtpServer(String ip,int port,String username,String password){
		boolean success=false;
		try{
			client=new FTPClient();
			client.connect(ip, port);
			client.setControlEncoding("GBK");
			if(FTPReply.isPositiveCompletion(client.getReplyCode())){
				if(client.login(username, password)){
					success=true;
					System.out.println("连接ftp服务器成功★★★★★★★★★★★★★★★★★★★★★★★");
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("连接ftp服务器出现异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	/**
	 * 断开ftp服务器连接
	 */
	public void disconnectFtpServer(){
		try{
			if(client.isConnected()){
				client.disconnect();
			}
			System.out.println("断开ftp服务器连接成功★★★★★★★★★★★★★★★★★★★★★★★");
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("断开ftp服务器连接出现异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
	}
	
	/**
	 * 下载ftp文件
	 * @param romotefile
	 * @param localfile
	 * @return
	 */
	public boolean downLoadFile(String romotefile,String localfile){
		FileOutputStream out=null;
		InputStream in=null;
		try{
			//设置被动模式
			client.enterLocalPassiveMode();
			//设置以二进制方式传输
			client.setFileType(FTP.BINARY_FILE_TYPE);
			//检查远程文件是否存在
			romotefile=new String(romotefile.getBytes("GBK"),"iso-8859-1");
			FTPFile[] files=client.listFiles(romotefile);
			if(files.length!=1){
				System.out.println("["+romotefile+"]:"+"FILE NOT FOUND(远程文件未找到)。。。。");
				return false;
			}
			
			//远程文件大小
			long romotesize=files[0].getSize();
			File file=new File(localfile);
			if(file.exists()){
				//本地文件大小
				long localsize=file.length();
				
				//判断本地文件大小是否大于远程文件大小
				if(localsize>=romotesize){
					System.out.println("["+romotefile+"]:"+"DOLOAD OVER(本地文件大于或等于远程文件，无需重新下载)。。。。");
					return true;
				}
				
				//进行断点续传，并记录状态
				out=new FileOutputStream(file,true);
				client.setRestartOffset(localsize);
				in=client.retrieveFileStream(romotefile);
				byte[] bytes=new byte[1024];
				long step=romotesize/10;
				step=step==0?1:step;//文件过小，step为1
				long process=localsize/step;
				int c;
				while((c=in.read(bytes))!=-1){
					out.write(bytes,0,c);
					localsize+=c;
					long nowprocess=localsize/step;
					if(nowprocess>process){
						process=nowprocess;
						if(process%10==0){
							System.out.println("正在下载远程文件，进度："+process);
						}
					}
				}
				in.close();
				out.close();
				boolean isDo=client.completePendingCommand();
				if(isDo){
					System.out.println("BREAK DOWNLOAD SUCCESS(断点续传下载成功)["+romotefile+"]★★★★★★★★★★★★★★★★★★★★★★★");
					return true;
				}else{
					System.out.println("BREAK DOWNLOAD FAIL(断点续传下载失败)["+romotefile+"]......");
					return false;
				}
			}else{
				String filedir=localfile.substring(0,localfile.lastIndexOf(File.separator));
				File pdir=new File(filedir);
				if(!pdir.exists()){
					pdir.mkdirs();
				}
				file.createNewFile();
				out=new FileOutputStream(file);
				in=client.retrieveFileStream(romotefile);
				byte[] bytes=new byte[1024];
				long step=romotesize/10;
				step=step==0?1:step;//文件过小，step为1
				long process=0;
				long localsize=0L;
				int c;
				while((c=in.read(bytes))!=-1){
					out.write(bytes,0,c);
					localsize+=c;
					long nowprocess=localsize/step;
					if(nowprocess>process){
						process=nowprocess;
						if(process%10==0){
							System.out.println("正在下载远程文件，进度："+process);
						}
					}
				}
				boolean uploadStatus=client.completePendingCommand();
				if(uploadStatus){
					System.out.println("DOWNLOAD SUCCESS(远程下载成功)["+romotefile+"]★★★★★★★★★★★★★★★★★★★★★★★");
					return true;
				}else{
					System.out.println("DOWNLOAD FAIL(远程下载失败)["+romotefile+"]☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
					return false;
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("DOWNLOAD EXCUTE ERROR(远程下载文件异常)["+romotefile+"]☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
			return false;
		}finally{
			try {
				if(out!=null){
					out.flush();
					out.close();
				}
				if(in !=null){
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("关闭IO流异常。。。。");
			}
		}
	}
	
	/***
	 * 修改ftp目录名称
	 * @param path
	 * @return
	 */
	public boolean changeDirectory(String path){
		boolean success=false;
		try {
			path=new String(path.getBytes("GBK"),"iso-8859-1");
			success= client.changeWorkingDirectory(path);
			System.out.println("移动远程目录指针成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("移动远程目录指针异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	
	/***
	 * 创建ftp目录
	 * 注意path需为从根目录开始的全路径地址，如/mhlg/test/a.txt或者/mhlg/test2
	 * @param path
	 * @return
	 */
	public boolean createDirectory(String path){
		boolean success=false;
		try {
			if(StringUtils.isNotBlank(path)){
				String[] dirarr=path.split(separator);
				if(dirarr!=null&&dirarr.length>0){
					String nowdir="separator";
					for(String dir:dirarr){
						if(StringUtils.isNotBlank(dir)){
							dir=new String(dir.getBytes("GBK"),"iso-8859-1");
							client.changeWorkingDirectory(nowdir);//切换至根目录
							client.makeDirectory(dir);
							nowdir=dir;
						}
					}
				}
			}
			success=true;
			System.out.println("创建远程新目录成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("创建远程新目录异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	/***
	 * 删除ftp上知道文件
	 * @return
	 */
	public boolean deleteFile(String filepath){
		boolean success=false;
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			client.changeWorkingDirectory(filepath.substring(0, filepath.lastIndexOf(separator)));
			filepath=new String(filepath.getBytes("GBK"),"iso-8859-1");
			success= client.deleteFile(filepath);
			System.out.println("删除远程文件成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("删除远程文件异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	

	/***
	 * 删除ftp文件夹目录:仅支持删除没有子目录的文件夹，如果文件夹内有内容，那么不能删除
	 * @param path
	 * @return
	 */
	public boolean removeDirectory(String path){
		boolean success=false;
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			client.changeWorkingDirectory(path.substring(0, path.lastIndexOf(separator)));
			path=new String(path.getBytes("GBK"),"iso-8859-1");
			success= client.removeDirectory(path);
			System.out.println("删除远程目录成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("删除远程目录异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	/**
	 * 删除ftp上文件夹目录以及目录中的所有目录,包含自己：支持删除文件夹，并级联删除子目录和文件
	 * @param path
	 * @return
	 */
	public boolean removeDirectoryDecade(String path){
		boolean success=false;
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			client.changeWorkingDirectory(path.substring(0, path.lastIndexOf(separator)));
			FTPFile[] files=client.listFiles(new String(path.getBytes("GBK"),"iso-8859-1"));
			if(files==null||files.length==0){
				success= client.removeDirectory(new String(path.getBytes("GBK"),"iso-8859-1"));
			}else{
				for(FTPFile f:files){
					String name=f.getName();
					if(f.isDirectory()){
						if(!name.equals(".")&&!name.equals("..")){
							success=removeDirectoryDecade(new String((path+separator+name).getBytes("GBK"),"iso-8859-1"));
						}
					}else if(f.isFile()){
						success=client.deleteFile(new String((path+separator+name).getBytes("GBK"),"iso-8859-1"));
					}
				}
			}
			client.removeDirectory(new String(path.getBytes("GBK"),"iso-8859-1"));
			System.out.println("级联删除远程目录成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("删除远程目录异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	
	/**
	 * 修改ftp文件名称
	 * @param oldname
	 * @return
	 */
	public boolean renameFile(String oldname,String newname){
		boolean success=false;
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			oldname=new String(oldname.getBytes("GBK"),"iso-8859-1");
			newname=new String(newname.getBytes("GBK"),"iso-8859-1");
			client.changeWorkingDirectory(oldname.substring(0, oldname.lastIndexOf(separator)));
			success=client.rename(oldname, newname);
			System.out.println("重命名远程文件成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("重命名远程文件异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return success;
	}
	
	/**
	 * 上传ftp文件
	 * @param remotefile
	 * @param localfile
	 * @return
	 */
	public String uploadFile(String remotefile,String localfile){
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			//设置以二进制方式传输
			client.setFileType(FTP.BINARY_FILE_TYPE);
			long romotesize=0;
			//检查远程文件是否存在
			remotefile=new String(remotefile.getBytes("GBK"),"iso-8859-1");
			FTPFile[] files=client.listFiles(remotefile);
			if(files.length==1){
				romotesize=files[0].getSize();
			}
			//远程文件大小
			File file=new File(localfile);
			long step=file.length();
			step=step==0?1:step;
			long process=0;
			long localbytes=0L;
			RandomAccessFile raf=new RandomAccessFile(file,"r");
			OutputStream out=client.appendFileStream(remotefile);
			if(romotesize>0){
				client.setRestartOffset(romotesize);
				process=romotesize/step;
				raf.seek(romotesize);
				localbytes=romotesize;
			}
			byte[] bytes=new byte[1024];
			
			int c=0;
			while((c=raf.read(bytes))!=-1){
				out.write(bytes,0,c);
				localbytes+=c;
				if(localbytes/step!=process){
					process=localbytes/step;
					if(process%10==0){
						System.out.println("文件上传进度："+process);
					}
				}
			}
			out.flush();
			raf.close();
			out.close();
			boolean result=client.completePendingCommand();
			if(result){
				System.out.println("上传文件成功★★★★★★★★★★★★★★★★★★★★★★★");
				return "BREAK UPLOAD SUCCESS";
			}else{
				System.out.println("上传文件异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
				return "BREAK UPLOAD FAIL";
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("上传文件异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
			return "UPLOAD ERROR";
		}
	}
	
	/**
	 * 获取ftp指定目录下的所有文件
	 * @return
	 */
	public FTPFile[] getFileList(String romotepath){
		FTPFile[] files=null;
		try {
			//设置被动模式
			client.enterLocalPassiveMode();
			client.changeWorkingDirectory(romotepath.substring(0, romotepath.lastIndexOf(separator)));
			files=client.listFiles(new String(romotepath.getBytes("GBK"),"iso-8859-1"));
			System.out.println("获取ftp指定目录下的所有文件成功★★★★★★★★★★★★★★★★★★★★★★★");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("获取ftp指定目录下的所有文件异常☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢");
		}
		return files;
	}
	
	public static void main(String[] args) throws IOException{
		FtpConnector connector=new FtpConnector();
		boolean success=connector.connectFtpServer("172.31.0.34", 21, "mobile_get", "mobile_get2018");
		//boolean success=connector.connectFtpServer("10.1.9.13", 21, "mhfkdata", "mhfkdata");
		System.out.println(success);
		
		connector.renameFile("/20180530100512mobileLocation.txt","/bak/20180530100512mobileLocation.txt");
		//connector.downLoadFile("/renwu_kyry/T010000000000-001721_20160728.zip", "D:/ftp/dowload/T010000000000-001721_20160728.zip");
		//connector.createDirectory("/ccc");
		//connector.renameFile("/wr斯蒂芬.csv","/test1.csv");
		//connector.uploadFile("/renwu_kyry/T0100000000斯蒂芬斯蒂芬森的123.zip","D:/ftp/dowload/T010000000000-001721_20160728.zip");
		//connector.removeDirectoryDecade("/斯蒂芬森的");
		//connector.deleteFile("/renwu_kyry/T0100000000斯蒂芬斯蒂芬森的321.zip");
		//connector.renameFile("/renwu_kyry/T0100000000斯蒂芬斯蒂芬森的123.zip","/renwu_kyry/T0100000000斯蒂芬斯蒂芬森的321.zip");
		connector.disconnectFtpServer();
	}
	
	
	
}
